home *** CD-ROM | disk | FTP | other *** search
Verilog source code | 1992-06-19 | 10.7 KB | 545 lines | [TEXT/MPS ] |
- /*
- 10 29 28-24 23-19 13-0
- 00 0/1 l/s rs ra abs - sext
-
- load rs, n(ra)
- store rs, n(ra)
-
- 10 29,18-15 28-24 23-19 14-0/4-0
- 01 type rd rs v/r (sext)
-
- add rd, rs, r/v 0
- sub rd, rs, r/v 1
- and rd, rs, r/v 2
- or rd, rs, r/v 3
- xor rd, rs, r/v 4
- lt rd, rs, r/v 5
- le rd, rs, r/v 6
- eq rd, rs, r/v 7
- lsh rd, rs, r/v 8
- jmp rd, rs, r/v 9
-
- 10 29 28-24 23-0
- 10 0/1 t/f r abs
-
- bt r, abs
- bf r, abs
-
- 10 29 28-24 23-0/15-0
- 11 0/1 /h r v
-
- const r, v 23-0
- consth r, v 15-0
-
-
-
- bus:
- clock
- reset
- a31_2
- d31_0
- r/w
- start
- ack
- near
- */
-
- module cpu2(clock, reset, a, d, rw, start, ack);
-
- input clock;
- input reset;
-
- inout [31: 0]d;
- reg [31: 0]dd;
- assign d = dd;
-
- output [31: 0]a;
- reg [31: 0]a;
-
- output rw;
- reg rw;
-
- output start;
- reg start;
-
- output near;
- reg near;
-
- input ack;
-
- wire [31: 0]ins_cache_in,
- write_data_out,
- write_addr_out,
- write_buffer_data,
- data_cache_in,
- s1,
- s2,
- s2a,
- exec_s1_data,
- exec_s2_data,
- dest;
-
- wire ins_cache_valid,
- data_cache_valid,
- write_buffer_full,
- write_buffer_ready,
- write_buffer_hit,
- do_branch,
- reg_stall;
-
- reg load_ins_cache,
- load_data_cache,
- write_buffer_write,
- exec_br,
- exec_bcond,
- exec_btest,
- ins_valid,
- exec_const,
- next_const,
- next_br,
- next_bcond,
- next_btest,
- next_lda,
- next_ls,
- next_st,
- exec_lda,
- exec_ls,
- exec_st,
- ls_busy,
- ls_start,
- ls_st,
- mem_busy,
- mem_read_ok,
- mem_write_ok,
- pc_read,
- pc_read_ok,
- mem_read,
- mem_write,
- next_stall,
- write_done;
-
- reg [31: 0]pc_addr,
- write_addr,
- write_ram_addr,
- pc,
- i,
- load_buff,
- write_buff,
- write_data_buff,
- exec_const_val,
- next_const_val,
- d_in;
-
- reg [ 4: 0]exec_op,
- next_op,
- next_s1,
- next_s2,
- next_d,
- next_s1_addr,
- next_s2_addr,
- exec_s1_addr,
- exec_s2_addr,
- load_addr;
-
- assign data_cache_in = (data_cache_valid?write_buffer_data:d);
-
- cache ins_cache(reset, pc_addr, ins_cache_in, ins_cache_valid, d_in, load_ins_cache);
- cache data_cache(reset, write_ram_addr, data_cache_in, data_cache_valid, data_cache_in, load_data_cache);
- write_buffer wb(reset, clock, write_ram_addr, write_data_buff, write_buffer_write, write_buffer_data, write_done, write_buffer_hit, write_buffer_full, write_buffer_ready, write_data_out, write_addr_out);
-
- //
- // reset
- //
-
- always @(negedge clock)
- if (~reset)
- begin
- start = 1;
- load_ins_cache = 0;
- load_data_cache = 0;
- write_buffer_write = 0;
- exec_br = 0;
- exec_bcond = 0;
- exec_btest = 0;
- ins_valid = 0;
- exec_const = 0;
- next_const = 0;
- next_br = 0;
- next_bcond = 0;
- next_btest = 0;
- next_lda = 0;
- next_ls = 0;
- next_st = 0;
- exec_lda = 0;
- exec_ls = 0;
- exec_st = 0;
- ls_busy = 0;
- ls_start = 0;
- ls_st = 0;
- pc_addr = 0;
- write_addr = 0;
- write_ram_addr = 0;
- i = 0;
- load_buff = 0;
- write_buff = 0;
- write_data_buff = 0;
- exec_const_val = 0;
- next_const_val = 0;
- write_done = 0;
- exec_op = 0;
- next_op = 0;
- next_s1 = 0;
- next_s2 = 0;
- next_d = 0;
- next_s1_addr = 0;
- next_s2_addr = 0;
- exec_s1_addr = 0;
- exec_s2_addr = 0;
- load_addr = 0;
- mem_busy = 0;
- pc_read = 0;
- mem_read = 0;
- mem_write = 0;
- pc_read_ok = 0;
- mem_read_ok = 0;
- mem_write_ok = 0;
- next_stall = 1;
- pc = 0;
- near = 0;
- end
-
-
- //
- // fetch
- //
-
- // initial $gr_waves("load_ins_cache", load_ins_cache,
- // "ins_valid", ins_valid,
- // "ins_cache_valid", ins_cache_valid,
- // "mem_start",mem_start,
- // "mem_busy",mem_busy,
- // "mem_read",mem_read,
- // "mem_write",mem_write,
- // "write_buffer_write", write_buffer_write,
- // "write_buffer_ready", write_buffer_ready,
- // "pc_addr",pc_addr);
- always @(negedge clock)
- if (reset) begin
- load_ins_cache = 0;
- #1
- if (~ins_valid) begin
- pc_addr = pc;
- pc = pc+4;
- @(posedge clock);
- if (ins_cache_valid) begin
- i = ins_cache_in;
- end else begin
- pc_read = 1;
- @(negedge clock);
- while (!pc_read_ok) // wait for any pending cycles to complete
- @(negedge clock);
- @(posedge clock);
- pc_read = 0;
- while (mem_busy) // wait for it to complete
- @(posedge clock);
- load_ins_cache = 1;
- i = d_in;
- end
- #1;
- ins_valid = 1;
- end
- end
-
-
- //
- // decode
- //
-
- assign reg_stall = ls_busy && (load_addr == next_s1 || load_addr == next_s2);
-
- /* initial $gr_waves("ins_valid", ins_valid,
- "ins_cache_valid", ins_cache_valid,
- "reg_stall", reg_stall,
- "next_op", next_op,
- "next_const", next_const,
- "next_br", next_br,
- "next_bcond",next_bcond,
- "next_btest",next_btest,
- "next_s1",next_s1,
- "next_s2",next_s2,
- "next_d",next_d,
- "next_lda",next_lda,
- "next_ls",next_ls,
- "next_st",next_st,
- "next_const_val",next_const_val);
- */
- always @(negedge clock)
- if (reset)
- if (~reg_stall && ins_valid) begin
- ins_valid = 0;
- case (i[31:30])
- 0: begin
- next_op = 0;
- next_const = 1;
- next_br = 0;
- next_bcond = 0;
- next_btest = 0;
- next_s1 = i[28:24];
- next_s2 = (i[29] ? i[23:19] : 0);
- next_d = 0;
- next_lda = (i[29] ? 0 : i[23:19]);
- next_ls = 1;
- next_st = i[29];
- next_const_val = {i[18],i[18],i[18],i[18],i[18],i[18],i[18],i[18],
- i[18],i[18],i[18],i[18],i[18],i[18],
- i[17:0]};
- #1;
- next_stall = ls_busy;
- end
- 1: begin
- next_op = i[18:15];
- next_const = i[29];
- next_br = i[18:15] == 9;
- next_bcond = 0;
- next_btest = 0;
- next_s1 = i[23:19];
- next_s2 = (i[29] ? 0 : i[4:0]);
- next_d = i[28:24];
- next_ls = 0;
- next_st = 0;
- next_const_val = {i[13],i[13],i[13],i[13],i[13],i[13],i[13],i[13],
- i[13],i[13],i[13],i[13],i[13],i[13],i[13],i[13],
- i[13],i[13],i[12:0]};
- #1;
- next_stall = reg_stall;
- end
- 2: begin
- next_op = 17;
- next_const = 1;
- next_br = 1;
- next_bcond = 1;
- next_btest = i[29];
- next_s1 = i[28:24];
- next_s2 = 0;
- next_d = 0;
- next_ls = 0;
- next_st = 0;
- next_const_val = {8'b0,i[23:0]};
- #1;
- next_stall = reg_stall;
- end
- 3: begin
- next_op = (i[29]?18:17);
- next_const = 1;
- next_br = 0;
- next_bcond = 0;
- next_btest = 0;
- next_s1 = (i[29]?i[28:24]:0);
- next_s2 = 0;
- next_d = i[28:24];
- next_ls = 0;
- next_st = 0;
- next_const_val= {8'b0,i[23:0]};
- #1;
- next_stall = reg_stall;
- end
-
- endcase
- end else begin
- #1
- next_stall = 1;
- end
-
- //
- // execute
- //
-
- assign s1 = (exec_s1_addr == 0 ? 0:
- exec_s1_addr == write_addr ? write_buff :
- exec_s1_addr == load_addr ? load_buff : exec_s1_data);
-
- assign s2a =(exec_s2_addr == 0 ? 0 :
- exec_s2_addr == write_addr ? write_buff :
- exec_s2_addr == load_addr ? load_buff : exec_s2_data);
-
- assign s2 = (exec_const ?exec_const_val : s2a);
-
- regfile rf(clock, write_addr, write_buff, exec_s1_addr, exec_s1_data, exec_s2_addr, exec_s2_data);
-
- alu aa(exec_op, dest, s1, s2);
-
- assign do_branch = exec_br && (!exec_bcond || exec_btest^dest[31]);
-
- /* initial $gr_waves("exec_op", exec_op,
- "exec_const", exec_const,
- "exec_br", exec_br,
- "exec_bcond",exec_bcond,
- "exec_btest",exec_btest,
- "exec_s1_addr",exec_s1_addr,
- "exec_s2_addr",exec_s2_addr,
- "write_addr",write_addr,
- "exec_lda",exec_lda,
- "exec_ls",exec_ls,
- "exec_st",exec_st,
- "exec_const_val",exec_const_val,
- "reg_stall",reg_stall);
- */
- always @(negedge clock)
- if (reset)
- if (next_stall) begin
- @(posedge clock)
- write_addr = 0;
- end else begin
- exec_op = next_op;
- exec_s1_addr = next_s1;
- exec_s2_addr = next_s2;
- exec_const_val = next_const_val;
- exec_const = next_const;
- exec_ls = next_ls;
- exec_st = next_st;
- exec_lda = next_lda;
- exec_br = next_br;
- exec_bcond = next_bcond;
- exec_btest = next_btest;
-
- @(posedge clock);
-
- if (do_branch) begin
- write_addr = next_d;
- write_buff = pc;
- #3
- pc = dest;
- end else
- if (exec_ls) begin
- write_addr = load_addr;
- write_data_buff = s2a;
- write_ram_addr = dest;
- write_buff = load_buff;
- load_addr = exec_lda;
- ls_busy = 1;
- ls_start = 1;
- ls_st = exec_st;
- end else begin
- write_addr = next_d;
- write_buff = dest;
- end
- end
- //
- // write-back
- //
- always @(negedge clock)
- if (reset)
- begin
- if (write_addr == load_addr)
- load_addr = 0;
- end
-
- //
- // LS machine
- //
-
- initial $gr_waves("write_buffer_full", write_buffer_full,
- "write_buffer_ready",write_buffer_ready,
- "write_ram_addr",write_ram_addr,
- "data_cache_valid",data_cache_valid,
- "exec_op",exec_op,
- "dest",dest,
- "s1",s1,
- "s2",s2);
-
- always @(negedge clock)
- if (reset) begin
- load_data_cache = 0;
- if (ls_start) begin
- ls_start = 0;
- if (ls_st) begin
- while (write_buffer_full) begin
- @(negedge clock);
- end
- if (data_cache_valid)
- load_data_cache = 1;
- write_buffer_write = 1;
- @(posedge clock);
- write_buffer_write = 0;
- load_data_cache = 0;
- end else begin
- @(posedge clock);
- if (data_cache_valid) begin
- load_buff = data_cache_in;
- end else
- if (write_buffer_hit) begin
- load_buff = write_buffer_data;
- end else begin
- mem_read = 1; // request memory
- @(negedge clock);
- while (!mem_read_ok) // wait for any pending cycles to complete
- @(negedge clock);
- @(posedge clock);
- mem_read = 0;
- while (mem_busy) // wait for it to complete
- @(posedge clock);
- load_data_cache = 1;
- load_buff = d_in;
- end
- end
- ls_busy = 0;
- end
- end
- //
- // write buffer requests to ram
- //
- always @(negedge clock)
- if (reset) begin
- write_done = 0;
- if (write_buffer_ready) begin
- mem_write = 1;
- @(negedge clock);
- while (!mem_write_ok) // wait for any pending cycles to complete
- @(negedge clock);
- @(posedge clock);
- mem_write = 0;
- while (mem_busy) // wait for it to complete
- @(posedge clock);
- write_done = 1;
- end
- end
-
-
- //
- // memory controller
- //
- always @(posedge clock)
- if (reset)
- if (mem_read || mem_write || pc_read) begin
- mem_busy = 1;
- if (mem_read) begin
- a = write_ram_addr;
- dd = 32'bz;
- rw = 1;
- mem_read_ok = 1;
- end else
- if (mem_write) begin
- a = write_addr_out;
- dd = write_data_out;
- rw = 0;
- mem_write_ok = 1;
- end else begin
- a = pc_addr;
- dd = 32'bz;
- rw = 1;
- pc_read_ok = 1;
- end
- start = 0;
- @(negedge clock);
- while (ack)
- @(negedge clock);
- d_in = d;
- mem_read_ok = 0;
- mem_write_ok = 0;
- pc_read_ok = 0;
- mem_busy = 0;
- start = 1;
- end
-
- endmodule
-